class cAllButton {
  cAllButton(int x, int y, String text, handler action) {
    this.x = x;
    this.y = y;
    this.text = text;
    this.action = action;
    colr = #F5F09C;
    enabled = true;
  }

  void checkMouseClick(int mx, int my) {
    if (enabled) {
      if (checkRange(mx, my)) {
        action.exec(this);
      }
    }
  }

  void paint() {
  }

  protected boolean checkRange(int mx, int my) {
    if (mx < x || my > y) {
      return false;
    }
    if (mx > (x + XRANGE) || my < (y - YRANGE)) {
      return false;
    }
    return true;
  }

  void enable() {
    enabled = true;
  }

  void disable() {
    enabled = false;
  }

  protected handler action;

  protected int x, y;
  protected String text;
  protected color colr;
  protected boolean enabled;
};

// button click detect range
final int XRANGE = 120;
final int YRANGE = 40;

// ===========================  //

class cclickButton extends cAllButton {
  cclickButton(int x, int y, String text, handler action) {
    super(x, y, text, action);
  }

  void paint() {
    if (faded) {
      fill(colr, 50);
    } else {
      fill(colr);
    }
    textSize(70);
    text(text, x, y);
    fill(colr);
  }

  void fade() {
    faded = true;
    disable();
  }

  void unfade() {
    faded = false;
    enable();
  }

  boolean faded;
};

// ===========================  //

class cradioButton extends cAllButton {
  cradioButton(int x, int y, String text, boolean checked, handler action) {
    super(x, y, text, action);
    this.checked = checked;
  }

  void paint() {
    textSize(40);
    fill(colr);
    if (checked) {
      text("*", x - 35, y + 10);
    }
    text(text, x, y);
  }

  boolean checked;
};

// ===========================  //

cclickButton btnGo = new cclickButton(1369, 120, "go", (cAllButton btn)->ButtonGo(btn));
cradioButton btn50 = new cradioButton(1189, 100, "50", true, (cAllButton btn)->Button50(btn));
cradioButton btn100 = new cradioButton(1189, 140, "100", false, (cAllButton btn)->Button100(btn));
cradioButton btn200 = new cradioButton(1189, 180, "200", false, (cAllButton btn)->Button200(btn));
cradioButton btn1000 = new cradioButton(1189, 220, "1000", false, (cAllButton btn)->Button1000(btn));

cAllButton[] allButtons = {btnGo, btn50, btn100, btn200, btn1000};
cradioButton[] allRadioButtons = {btn50, btn100, btn200, btn1000};

void uncheckAllRadioButtons() {
  for (cradioButton e : allRadioButtons) {
    e.checked = false;
  }
}

void disableAllButtons() {
  for (cAllButton e : allButtons) {
    e.disable();
  }
}

void enableAllButtons() {
  for (cAllButton e : allButtons) {
    e.enable();
  }
}

// ============ button handlers ===============  //

void ButtonGo(cAllButton btn) {
  // generate 2 random number
  int_a = (int)random(1, range); // [1, range)
  int_b = (int)random(1, range); // [1, range)

  // then get their GCD
  gcd(int_a, int_b);

  // position of screen start to show
  x_pos = X_POS_INIT;
  y_pos = Y_POS_INIT;

  disableAllButtons();
  ((cclickButton)(btn)).fade();
  drawBasicGUI(); // go button faded, redraw
  stateMachine = 1;
}

// ===========================  //

void commonActionRadioBtn(cAllButton btn) {
  uncheckAllRadioButtons();
  ((cradioButton)(btn)).checked = true;
  stateMachine = 0;
  println("range set to " + (range - 1));
}

void Button50(cAllButton btn) {
  range = 51;
  commonActionRadioBtn(btn);
}

void Button100(cAllButton btn) {
  range = 101;
  commonActionRadioBtn(btn);
}

void Button200(cAllButton btn) {
  range = 201;
  commonActionRadioBtn(btn);
}

void Button1000(cAllButton btn) {
  range = 1001;
  commonActionRadioBtn(btn);
}
